package cn.unknowpupil.init.service.system.impl;

import cn.unknowpupil.init.domain.system.SysRole;
import cn.unknowpupil.init.domain.system.SysUser;
import cn.unknowpupil.init.exceptions.HealthException;
import cn.unknowpupil.init.service.system.ISysPermissionService;
import cn.unknowpupil.init.service.system.ISysRoleService;
import cn.unknowpupil.init.mapper.system.SysRoleMapper;
import cn.unknowpupil.init.utils.strings.StringUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * Created at 2020-11-13 by  w10g <br>
 * Initialize SysRole  ... <br>
 * 角色表 核心业务处理实现类
 *
 * @author unknowpupil
 * @since 0.0.1
 */
@Service
public class SysRoleServiceImpl extends ServiceImpl<SysRoleMapper, SysRole> implements ISysRoleService {


    @Resource
    private ISysPermissionService sysPermissionService;

    /**
     * 新增
     *
     * @param sysRole {@link SysRole}  角色表
     * @return {@link SysRole}
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean create(SysRole sysRole) {
        boolean result = save(sysRole);
        if (result) {
            if (sysRole.getPermissionIds().length > 0) {
                result = sysPermissionService.insertRolePermission(sysRole.getId(), sysRole.getPermissionIds());
                if (!result) {
                    throw new HealthException("新增失败，请重试");
                }
            }
        }

        return result;
    }

    /**
     * 详情
     *
     * @param id {@code Long}   SysRole ID
     * @return {@link SysRole}
     */
    @Override
    public SysRole info(Long id) {
        return getById(id);
    }

    /**
     * 删除
     *
     * @param ids {@code Long}   ids
     * @return {@link SysRole}
     */
    @Override
    public boolean delete(Long[] ids) {
        List<Long> collect = Stream.of(ids).collect(Collectors.toList());

        collect.forEach(o -> {
            if (o == 1) {
                throw new HealthException("超级管理员权限，无法删除");
            }
            if (sysPermissionService.countRolePermission(o) > 0) {
                throw new HealthException("删除失败，该角色已被分配给权限");
            }
            if (baseMapper.countRoleUser(o) > 0) {
                throw new HealthException("删除失败，该角色已被分配给用户");
            }
        });

        return removeByIds(collect);
    }


    /**
     * 修改
     *
     * @param sysRole {@link SysRole}  角色表
     * @return {@link SysRole}
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean update(SysRole sysRole) {

        sysPermissionService.deleteAllPermissionByRole(sysRole.getId());

        boolean result = false;
        if (sysRole.getPermissionIds().length > 0) {
            result = sysPermissionService.insertRolePermission(sysRole.getId(), sysRole.getPermissionIds());
            if (!result) {
                throw new HealthException("修改失败，请重试");
            }
        }

        result = updateById(sysRole);
        if (!result) {
            throw new HealthException("修改失败，请重试");
        }
        return result;
    }




    @Override
    public Set<String> getRolePermission(SysUser user) {
        Set<String> roles = new HashSet<String>();
        // 管理员拥有所有权限
        if (user.isAdmin()) {
            roles.add("USER_ADMIN");
        } else {
            roles.addAll(selectRolePermissionByUserId(user.getId()));
        }
        return roles;
    }

    /**
     * 根据角色查询权限
     *
     * @param id
     * @return
     */
    private Set<String> selectRolePermissionByUserId(Long id) {

        List<SysRole> sysRoles = baseMapper.selectRolePermissionByUserId(id);
        Set<String> permsSet = new HashSet<>();
        for (SysRole perm : sysRoles) {
            if (!Objects.isNull(perm)) {
                permsSet.addAll(Arrays.asList(perm.getRole().trim().split(",")));
            }
        }
        return permsSet;
    }


    @Override

    public Set<String> getMenuPermission(SysUser user) {
        Set<String> perms = new HashSet<String>();
        // 管理员拥有所有权限
        if (user.isAdmin()) {
            perms.add("*:*:*");
        } else {
            perms.addAll(sysPermissionService.selectMenuPermsByUserId(user.getId()));
        }
        return perms;
    }

    @Override
    public void checkRoleAllowed(SysRole role) {
        if (StringUtils.isNotNull(role.getId()) && role.isAdmin()) {
            throw new HealthException("不允许操作超级管理员角色");
        }
    }

    @Override
    public Long selectRoleByUserId(Long id) {
        return baseMapper.selectRoleByUserId(id);

    }

    @Override
    public IPage<SysRole> page(int current, int size, SysRole sysRole) {
        IPage<SysRole> page = new Page<>(current,size);
        LambdaQueryWrapper<SysRole> wrapper = new LambdaQueryWrapper<>();
        // TODO 查询
        // TODO 排序

        return super.page(page, wrapper);
    }



    /**
     * 清理缓存
     *
     * @param id /
     */
    public void delCaches(Long id, List<SysUser> users) {
//        redisUtils.delByKeys(CacheKeyConstants.DATE_USER, userIds);
//        redisUtils.delByKeys(CacheKeyConstants.MENU_USER, userIds);
//        redisUtils.delByKeys(CacheKeyConstants.ROLE_AUTH, userIds);
//        redisUtils.del(CacheKeyConstants.ROLE_ID + id);
    }
}
